package com.minimalist.lindi.manager;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.http.HttpStatus;
import com.minimalist.common.config.exception.BusinessException;
import com.minimalist.common.entity.basic.vo.file.FileVO;
import com.minimalist.common.entity.lindi.enums.LindiSubsidyApplicationEnum;
import com.minimalist.common.entity.lindi.po.LindiEnterpriseAccount;
import com.minimalist.common.entity.lindi.po.LindiSubsidyApplication;
import com.minimalist.common.entity.lindi.po.LindiSubsidyApplicationFile;
import com.minimalist.common.entity.lindi.vo.enterpriseaccount.LindiEnterpriseAccountVO;
import com.minimalist.common.entity.lindi.vo.subsidyapplication.LindiSubsidyApplicationApprovalVO;
import com.minimalist.common.entity.lindi.vo.subsidyapplicationfile.LindiSubsidyApplicationFileVO;
import com.minimalist.common.feign.client.basic.FileFeignClient;
import com.minimalist.common.response.R;
import com.minimalist.lindi.mapper.LindiEnterpriseAccountMapper;
import com.minimalist.lindi.mapper.LindiSubsidyApplicationFileMapper;
import com.minimalist.lindi.mapper.LindiSubsidyApplicationMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 林地指标交易平台_补贴申请管理器
 *
 * @author 11987
 */
@Component
public class LindiSubsidyApplicationManager{

    private static final Logger logger = LoggerFactory.getLogger(LindiSubsidyApplicationManager.class);

    @Autowired
    private LindiSubsidyApplicationFileMapper lindiSubsidyApplicationFileMapper;

    @Autowired
    private LindiSubsidyApplicationMapper lindiSubsidyApplicationMapper;

    @Autowired
    private LindiEnterpriseAccountMapper lindiEnterpriseAccountMapper;

    @Autowired
    private FileFeignClient fileFeignClient;

    public LindiEnterpriseAccountVO getEnterpriseAccountByEnterpriseId(
            Long enterpriseId){
        LindiEnterpriseAccount lindiEnterpriseAccount = lindiEnterpriseAccountMapper
                .selectEnterpriseAccountByEnterpriseAccountId(enterpriseId);
        Assert.notNull(lindiEnterpriseAccount, () -> new BusinessException("企业账号信息不存在"));
        return BeanUtil.copyProperties(lindiEnterpriseAccount, LindiEnterpriseAccountVO.class);
    }

    /**
     * 根据补贴申请ID获取文件列表
     *
     * @param subsidyApplicationId 补贴申请ID
     * @return 文件列表
     */
    public List<LindiSubsidyApplicationFileVO>
    getSubsidyApplicationFileListBySubsidyApplicationId(
            Long subsidyApplicationId){
        List<LindiSubsidyApplicationFile> lindiSubsidyApplicationFiles =
                lindiSubsidyApplicationFileMapper
                        .selectFileListBySubsidyApplicationId(subsidyApplicationId);

        if (lindiSubsidyApplicationFiles.isEmpty()){
            return List.of();
        }

        List<Long> fileIdList = lindiSubsidyApplicationFiles.stream()
                .map(LindiSubsidyApplicationFile::getFileId).toList();

        R<List<FileVO>> filesResult = fileFeignClient.getFileListByFileIds(fileIdList);
        Assert.isTrue(filesResult.getCode() == HttpStatus.HTTP_OK
                        && filesResult.getData() != null
                , () -> new BusinessException("获取文件信息失败"));

        List<FileVO> fileVOList = filesResult.getData();

        // 将LindiSubsidyApplicationFile转换为LindiSubsidyApplicationFileVO并设置文件信息
        return lindiSubsidyApplicationFiles.stream()
                .map(subsidyFile -> {
                    LindiSubsidyApplicationFileVO vo = BeanUtil.copyProperties(
                            subsidyFile, LindiSubsidyApplicationFileVO.class);

                    // 设置文件信息
                    fileVOList.stream()
                            .filter(fileVO -> fileVO.getFileId().equals(subsidyFile.getFileId()))
                            .findFirst()
                            .ifPresent(vo::setFile);

                    return vo;
                })
                .collect(Collectors.toList());
    }

    /**
     * 批量插入补贴申请文件
     *
     * @param subsidyApplicationFiles 文件列表
     */
    @Transactional(rollbackFor = Exception.class)
    public void insertSubsidyApplicationFiles(
            List<LindiSubsidyApplicationFileVO> subsidyApplicationFiles){
        if (subsidyApplicationFiles == null || subsidyApplicationFiles.isEmpty()){
            return;
        }
        List<LindiSubsidyApplicationFile> list = subsidyApplicationFiles.stream()
                .map(file ->
                        BeanUtil.copyProperties(file, LindiSubsidyApplicationFile.class)
                )
                .collect(Collectors.toList());
        lindiSubsidyApplicationFileMapper.insertBatch(list);
    }

    /**
     * 根据补贴申请ID删除所有文件
     *
     * @param subsidyApplicationId 补贴申请ID
     */
    @Transactional(rollbackFor = Exception.class)
    public void deleteSubsidyApplicationFilesBySubsidyApplicationId(
            Long subsidyApplicationId){
        List<LindiSubsidyApplicationFile> lindiSubsidyApplicationFiles =
                lindiSubsidyApplicationFileMapper
                        .selectFileListBySubsidyApplicationId(subsidyApplicationId);
        List<Long> fileIdList = lindiSubsidyApplicationFiles.stream()
                .map(LindiSubsidyApplicationFile::getFileId).toList();
        try{
            R<Void> result = fileFeignClient.deleteBatchFiles(fileIdList);
            if (result.getCode() != HttpStatus.HTTP_OK){
                logger.warn("批量删除文件失败，fileIds: {}, 错误信息: {}", fileIdList, result.getMessage());
            }
        } catch (Exception e){
            logger.warn("批量删除文件时发生异常，fileIds: {}, 异常信息: {}", fileIdList, e.getMessage());
        }
        lindiSubsidyApplicationFileMapper.deleteBySubsidyApplicationId(
                subsidyApplicationId);
    }

    /**
     * 根据文件ID删除补贴申请文件
     *
     * @param fileId 文件ID
     */
    @Transactional(rollbackFor = Exception.class)
    public void deleteSubsidyApplicationFilesByFileId(Long fileId){
        // 只删除数据库记录，文件删除由Service层处理
        lindiSubsidyApplicationFileMapper.deleteByFileId(fileId);
    }

    /**
     * 根据文件类型和补贴申请ID插入文件
     *
     * @param fileIds              文件ID列表
     * @param subsidyApplicationId 补贴申请ID
     * @param fileType             文件类型
     */
    @Transactional(rollbackFor = Exception.class)
    public void insertSubsidyApplicationFilesByType(
            List<Long> fileIds, Long subsidyApplicationId, String fileType){
        if (fileIds == null || fileIds.isEmpty()){
            return;
        }
        List<LindiSubsidyApplicationFile> list = fileIds.stream()
                .map(fileId -> LindiSubsidyApplicationFile.builder()
                        .subsidyApplicationId(subsidyApplicationId)
                        .fileId(fileId)
                        .fileType(fileType)
                        .build())
                .collect(Collectors.toList());
        lindiSubsidyApplicationFileMapper.insertBatch(list);
    }

    /**
     * 根据文件类型删除补贴申请文件
     *
     * @param subsidyApplicationId 补贴申请ID
     * @param fileType             文件类型
     */
    @Transactional(rollbackFor = Exception.class)
    public void deleteSubsidyApplicationFilesBySubsidyApplicationIdAndFileType(
            Long subsidyApplicationId, String fileType){
        List<LindiSubsidyApplicationFile> lindiSubsidyApplicationFiles =
                lindiSubsidyApplicationFileMapper
                        .selectFileListBySubsidyApplicationIdAndFileType(
                                subsidyApplicationId, fileType);
        if (lindiSubsidyApplicationFiles == null || lindiSubsidyApplicationFiles.isEmpty()){
            return;
        }
        List<Long> fileIdList = lindiSubsidyApplicationFiles.stream()
                .map(LindiSubsidyApplicationFile::getFileId).toList();
        try{
            R<Void> result = fileFeignClient.deleteBatchFiles(fileIdList);
            if (result.getCode() != HttpStatus.HTTP_OK){
                logger.warn("批量删除文件失败，fileIds: {}, 错误信息: {}", fileIdList, result.getMessage());
            }
        } catch (Exception e){
            logger.warn("批量删除文件时发生异常，fileIds: {}, 异常信息: {}", fileIdList, e.getMessage());
        }
        lindiSubsidyApplicationFileMapper.deleteBySubsidyApplicationIdAndFileType(
                subsidyApplicationId, fileType);
    }

    public List<LindiSubsidyApplicationFileVO>
    getSubsidyApplicationFileListBySubsidyApplicationIdAndFileType(
            Long subsidyApplicationId
            , String fileType){
        List<LindiSubsidyApplicationFile> lindiSubsidyApplicationFiles =
                lindiSubsidyApplicationFileMapper
                        .selectFileListBySubsidyApplicationIdAndFileType(
                                subsidyApplicationId, fileType);

        if (lindiSubsidyApplicationFiles.isEmpty()){
            return List.of();
        }

        List<Long> fileIdList = lindiSubsidyApplicationFiles.stream()
                .map(LindiSubsidyApplicationFile::getFileId).toList();

        R<List<FileVO>> filesResult = fileFeignClient.getFileListByFileIds(fileIdList);
        Assert.isTrue(filesResult.getCode() == HttpStatus.HTTP_OK
                        && filesResult.getData() != null
                , () -> new BusinessException("获取文件信息失败"));

        List<FileVO> fileVOList = filesResult.getData();

        // 将LindiSubsidyApplicationFile转换为LindiSubsidyApplicationFileVO并设置文件信息
        return lindiSubsidyApplicationFiles.stream()
                .map(subsidyFile -> {
                    LindiSubsidyApplicationFileVO vo = BeanUtil.copyProperties(
                            subsidyFile, LindiSubsidyApplicationFileVO.class);

                    // 设置文件信息
                    fileVOList.stream()
                            .filter(fileVO -> fileVO.getFileId().equals(subsidyFile.getFileId()))
                            .findFirst()
                            .ifPresent(vo::setFile);

                    return vo;
                })
                .collect(Collectors.toList());
    }

    /**
     * 审批补贴申请
     *
     * @param approvalVO 审批信息
     */
    @Transactional(rollbackFor = Exception.class)
    public void approveSubsidyApplication(LindiSubsidyApplicationApprovalVO approvalVO){
        // 查询补贴申请信息
        LindiSubsidyApplication subsidyApplication = lindiSubsidyApplicationMapper
                .selectSubsidyApplicationBySubsidyApplicationId(approvalVO.getSubsidyApplicationId());
        Assert.notNull(subsidyApplication, () -> new BusinessException("补贴申请不存在"));

        // 根据审批结果更新补贴申请状态
        if (approvalVO.getApprovalResult() == 1){
            // 审批通过
            Integer nextStatus = Integer.valueOf(subsidyApplication.getSubsidyStatus() + 1);
            subsidyApplication.setSubsidyStatus(String.valueOf(nextStatus));
        } else if (approvalVO.getApprovalResult() == 2){
            // 审批驳回
            subsidyApplication.setSubsidyStatus(LindiSubsidyApplicationEnum
                    .StatusEnum.REJECTED.getCode().toString());
        } else{
            throw new BusinessException("无效的审批结果");
        }

        // 更新补贴申请信息
        subsidyApplication.setUpdateId(approvalVO.getUpdateId());
        subsidyApplication.setUpdateTime(approvalVO.getUpdateTime());

        int updateResult = lindiSubsidyApplicationMapper.update(subsidyApplication);
        Assert.isTrue(updateResult == 1, () -> new BusinessException("更新补贴申请状态失败"));

        // TODO: 可以在这里添加审批记录的保存逻辑
        // 例如保存到审批历史表中
    }
}